﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Diagnostics;
using System.Web.UI.WebControls;

public class ControlBinder<TListItem, TBusinessItem> where TListItem : Control
{
    protected TListItem ListItem { get; set; }
    public TBusinessItem BusinessItem { get; set; }

    public ControlBinder(TListItem listItem, object dataItem)
    {
        ListItem = listItem;
        BusinessItem = (TBusinessItem)dataItem;
    }

    public void Bind(Action<TListItem> bindAction)
    {
        bindAction(ListItem);
    }

    public Control FindControl(string controlID)
    {
        return ListItem.FindControl(controlID);
    }

    public TControlType Find<TControlType>(string id) where TControlType : System.Web.UI.Control
    {
        Debug.Assert(ListItem != null);
        Debug.Assert(!string.IsNullOrEmpty(id));
        Debug.Assert(ListItem.HasControls());

        if (ListItem == null) return null;

        if (string.IsNullOrEmpty(id)) return null;

        if (!ListItem.HasControls()) return null;

        var searchControl = ListItem.FindControl(id);

        if (searchControl == null) return null;

        Debug.Assert(searchControl.GetType().IsAssignableFrom(typeof(TControlType)));

        return searchControl as TControlType;
    }

    public static void Bind(TListItem tEntity, Action<ControlBinder<TListItem, TBusinessItem>> action)
    {
        EntityWrapper e = EntityWrapper.Bind(tEntity);

        if (e.ItemType == ListItemType.AlternatingItem || e.ItemType == ListItemType.Item)
        {
            action(new ControlBinder<TListItem, TBusinessItem>(tEntity, e.DataItem));
        }
    }

    private class EntityWrapper
    {
        public ListItemType ItemType { get; private set; }
        public object DataItem { get; private set; }

        public EntityWrapper(ListItemType itemType, object dataItem)
        {
            this.ItemType = itemType;
            this.DataItem = dataItem;
        }

        public static EntityWrapper Bind(object tEntity)
        {
            EntityWrapper w = null;

            switch (tEntity.GetType().Name)
            {
                case "DataGridItem":
                    var d = (DataGridItem)tEntity;
                    w = new EntityWrapper(d.ItemType, d.DataItem);
                    break;
                case "RepeaterItem":
                    var r = (RepeaterItem)tEntity;
                    w = new EntityWrapper(r.ItemType, r.DataItem);
                    break;
                default:
                    break;
            }

            return w;
        }
    }
}

